﻿using Reticulum.User;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Data.SqlClient;
using System.Threading;

namespace Reticulum.工具类
{
    class Download
    {
        /*
         * 思路：
         *     点击下载，判断Action委托数组里的委托异步线程有没有执行完的，
         *     如果有，则加入Action委托数组，如果没有，则加入等待下载集合，
         *     直到Action数组里的委托执行状态为结束时.
         * */

        public static void StartDownLoad()//获取文件各种信息
        {
            if (ThisMyInfo.DownloadState == "1")
            {
                MessageBox.Show("你被禁止进行下载");
            }
            else
            {
                //获得下载任务的属性
                string fileid = null;//文件ID
                string filename = null;//文件名
                string filesuffix = null;//文件后缀名
                string filesize = null;

                //////////////////////////文件大小有问题
                string sql = string.Format("select FileDownName,FlieID,FlieName,FlieSuffix,FlieLength from FlieInfo where original_File_name='{0}'", Client.choice_term);
                SqlDataReader reader = DBHelps.Select(sql);
                while (reader.Read())
                {
                    Client.fileNames = reader["FileDownName"].ToString();
                    fileid = reader["FlieID"].ToString();
                    filename = reader["FlieName"].ToString();
                    filesuffix = reader["FlieSuffix"].ToString();
                    filesize = reader["FlieLength"].ToString();
                }
                reader.Close();
                DBHelps.reader = null;


                //右键菜单的下载功能



                //可能要获取的路径名
                //string localFilePath = "", fileNameExt = "", newFileName = "", FilePath = "";
                // SaveFileDialog saveFileDialog = new SaveFileDialog();

                // localFilePath = "C: \\Users\\Overlord\\Desktop\\007ZrlpSly1gff63y2otgj30u0140e8f.jpg";
                //设置文件类型
                //书写规则例如：txt files(*.txt)|*.txt
                Loads.client.saveFileDialog1.Filter = "All files(*.*)|*.*|txt files(*.txt)|*.txt|xls files(*.xls)|*.xls";

                Loads.client.saveFileDialog1.FileName = filename;//设置默认文件名（可以不设置）

                //saveFileDialog.DefaultExt = "xml";//主设置默认文件extension（可以不设置）

                Loads.client.saveFileDialog1.AddExtension = true;//获取或设置一个值，该值指示如果用户省略扩展名，文件对话框是否自动在文件名中添加扩展名。（可以不设置）

                Loads.client.saveFileDialog1.FilterIndex = 1;//设置默认文件类型显示顺序（可以不设置）
                
                Loads.client.saveFileDialog1.RestoreDirectory = true;//保存对话框是否记忆上次打开的目录

                DialogResult result = Loads.client.saveFileDialog1.ShowDialog();


                //点了保存按钮进行下载
                if (result == DialogResult.OK)
                {
                    string strPath = Loads.client.saveFileDialog1.FileName + filesuffix;//获取选择的全路径
                    string strName = strPath.Substring(strPath.LastIndexOf("\\") + 1);//获取文件名
                    
                    if (File.Exists(strPath))
                    {
                        DialogResult result1 = MessageBox.Show("文件已存在！是否继续下载？", "", MessageBoxButtons.YesNo);
                        if (result1 == DialogResult.Yes)
                        {
                            strPath = TraverseRename(strPath, 0, Loads.client.saveFileDialog1.FileName, filesuffix);//重绘文件名的方法
                            strName = strPath.Substring(strPath.LastIndexOf("\\") + 1);//获取文件名

                            CreateDownloadTask(strPath, strName, fileid,filesuffix,filesize);//创建下载日志并开始下载
                            
                        }
                        else
                        { return; }//跳出下载
                    }
                    else
                    { CreateDownloadTask(strPath, strName, fileid, filesuffix, filesize); }//创建下载
                }
            }
        }
        public static void CreateDownloadTask(string strPath, string strName, string fileid,string filesuffix,string filesize)//创建下载任务的方法
        {
            //文件不存在则进行下载

            //创建下载日志
            string sqlstr1 = string.Format("insert into FlieTeamLog(FlieID,UserID,FileDownName,SaveName,OperationState,Createdate,DownloadLocation,FileSize,FileSuffix)" +
                "values({0}, {1}, '{2}', '{3}', '{4}', '{5}', '{6}',{7},'{8}')", fileid, ThisMyInfo.UserID, Client.fileNames, strName, null, DateTime.Now, strPath, filesize,filesuffix);

            if (DBHelps.Command(sqlstr1))
            {
                //判断加入的任务队列,True为等待队列、False为下载队列
                bool IfWait = true;

                //循环判断下载队列是否有位置
                for (int i = 0; i < DownloadList.Length; i++)
                {
                    if (DownloadList[i] == null)//如果下载队列为空则进行下载
                    {   //加入的任务队列为下载队列
                        IfWait = false;

                        //更新下载日志为正在下载
                        string sqlstr2 = string.Format("update FlieTeamLog set OperationState='正在下载' where SaveName='{0}'", strName);
                        DBHelps.Command(sqlstr2);

                        //赋值匿名方法 到 Action委托数组，并开启新线程进行下载
                        DownloadList[i] = DownloadCMD;//delegate

                        //开始执行异步委托
                        DownloadList[i].BeginInvoke(i, strPath, null, null);
                        break;
                    }
                }
                if (IfWait)
                {
                    //如果队列中全都在进行下载则进入等待队列
                    string sqlstr = string.Format("update FlieTeamLog set OperationState='等待下载' where SaveName='{0}'", strName);
                    DBHelps.Command(sqlstr);

                    for (int i = 0; i < WaitloadList.Length; i++)
                    {
                        if (WaitloadList[i] != null)
                        {
                            WaitloadList[i] = DownloadCMD;
                        }
                    }

                    LoadListView.CountQueue();//刷新队列

                    return;
                }
            }
            else
            {
                MessageBox.Show("创建任务失败！");
            }
        }
        public static void DownloadCMD(int overindex, string localFilePath)//异步委托执行下载
        {
            //这个有问题
            string sql2 = string.Format("select FileDownName from FlieInfo where original_File_name='{0}'", Client.choice_term);
            SqlDataReader reader2 = DBHelps.Select(sql2);
            while (reader2.Read())
            {
                Client.fileNames = reader2["FileDownName"].ToString();
            }
            reader2.Close();
            DBHelps.reader = null;

            //测试：暂停线程3分钟
            //Thread.Sleep(60000 * 3);

            //下载ation地址
            string remoteUri = string.Format($"http://112.74.46.59//api/downfile" + "?filename={0}", Client.fileNames);

            WebClient myWebClient = new WebClient();
            myWebClient.DownloadFile(remoteUri, localFilePath);//两个参数，url地址与文件名


            //下载完成：更新下载日志为完成下载
            string sqlstr3 = string.Format("update FlieTeamLog set OperationState='下载完成' where FileDownName='{0}'", Client.fileNames);
            DBHelps.Command(sqlstr3);

            //删除对应的下载任务队列
            DownloadList[overindex] = null;

            //刷新队列
            LoadListView.CountQueue();

            MessageBox.Show("下载成功！");

            /*
            for (int i = 0; i < WaitloadList.Length; i++)
            {
                if (WaitloadList[i] != null)
                {
                    DownloadList[overindex] = WaitloadList[i];

                }
            }
            */
            //下载成功后打开文件所在文件夹 提示： 如果文件出现错误  请联系管理员
            /*
            DialogResult Downloadresult = MessageBox.Show("下载成功！" + "\n\r" + "是否打开文件所在的文件夹？", "打开文件", MessageBoxButtons.YesNo);
            if (Downloadresult == DialogResult.Yes)
            {
                Process p = new Process();
                p.StartInfo.FileName = xin;//文件路径

                p.StartInfo.Arguments = @localFilePath + Client.extension_1;//具体文件会高亮显示
                p.Start();
                System.Diagnostics.Process.Start(xin); //打开此文件。
            }
            */
        }
        public static string TraverseRename(string Flienames,int index,string Rename, string filesuffix)//遍历循环，重新绘制文件名的方法
        {
            //string Flienames：最终的重绘名字 也是返回值
            //int index：表示重复的次数
            //string Rename：表示原始名字
            //string filesuffix：文件的下标
            if (File.Exists(Flienames))
            {
                //如果文件存在,
                index++;

                Flienames = Rename + "(" + index.ToString() + ")" + filesuffix;

                Flienames = TraverseRename(Flienames, index,Rename, filesuffix);

                return Flienames;
            }

            return Flienames;
        }
        public static void RightClickDownLoad()
        {
            if (ThisMyInfo.DownloadState == "1")
            {
                MessageBox.Show("你被禁止进行下载");
            }
            else//如果权限没被禁用
            {
                string fileid = null;//获得文件ID

                string sql = string.Format("select FileDownName,FlieID from FlieInfo where original_File_name='{0}'", Client.choice_term);
                SqlDataReader reader = DBHelps.Select(sql);
                while (reader.Read())
                {
                    Client.fileNames = reader["FileDownName"].ToString();
                    fileid = reader["FlieID"].ToString();

                }
                reader.Close();
                DBHelps.reader = null;

                string ar = Directory.GetCurrentDirectory() + "\\../../Changes下载文件/" + Client.choice_term;//放置到目标

                if (File.Exists(ar))
                {
                    //已有文件
                    MessageBox.Show("下载成功！");
                }
                else//如果没有文件则进行下载
                {
                    //将操作添加到数据库的日志表
                    string sqlstr1 = string.Format("insert into FlieTeamLog(FlieID,UserID,FileDownName,OperationState,Createdate,DownloadLocation)" +
                                "values({0}, {1}, '{2}', '{3}', '{4}', '{5}')", fileid, ThisMyInfo.UserID, Client.fileNames, null, DateTime.Now, ar);


                    if (DBHelps.Command(sqlstr1))
                    {

                        bool IfWait = true;//判断文件加入的队列
                        //MessageBox.Show("无此文件");
                        //默认下载后打开
                        for (int i = 0; i < DownloadList.Length; i++)//循环判断下载队列
                        {
                            if (DownloadList[i] == null)//如果下载队列有空位则进行下载
                            {
                                IfWait = false;

                                string sqlstr2 = string.Format("update FlieTeamLog set OperationState='正在下载' where FileDownName='{0}'", Client.fileNames);
                                DBHelps.Command(sqlstr2);

                                DownloadList[i] = delegate//使用匿名方法，存入至Action的数组中
                                {
                                    WebClient myWebClient = new WebClient();
                                    string remoteUri = string.Format($"http://112.74.46.59//api/downfile" + "?filename={0}", Client.fileNames);
                                    myWebClient.DownloadFile(remoteUri, ar);

                                    MessageBox.Show("下载成功！");
                                    DownloadList[i] = null;//清空下载位

                                    string sqlstr3 = string.Format("update FlieTeamLog set OperationState='传输完成' where FileDownName='{0}'", Client.fileNames);
                                    DBHelps.Command(sqlstr3);

                                    //下载完成刷新队列
                                    LoadListView.CountQueue();
                                };
                                DownloadList[i].BeginInvoke(i, ar, null, null);//开启新线程执行匿名方法
                                break;
                            }
                        }

                        if (IfWait)
                        {
                            string sqlstr = string.Format("update FlieTeamLog set OperationState='等待下载' where FileDownName='{0}'", Client.fileNames);
                            DBHelps.Command(sqlstr);
                            //如果队列中全都在进行下载则进入等待队列
                        }
                    }
                    else
                    {
                        MessageBox.Show("创建下载任务失败!");
                    }
                }
            }
        }


        //下载队列
        public static Action<int, string> action1;
        public static Action<int, string> action2;
        public static Action<int, string> action3;

        //等待队列
        public static Action<int, string> wait1;
        public static Action<int, string> wait2;
        public static Action<int, string> wait3;
        public static Action<int, string> wait4;
        public static Action<int, string> wait5;
        public static Action<int, string> wait6;
        public static Action<int, string> wait7;

        public static Action<int, string>[] DownloadList = new Action<int, string>[] { action1, action2, action3 };
        public static Action<int, string>[] WaitloadList = new Action<int, string>[] { wait1, wait2, wait3, wait4, wait5, wait6, wait7 };
















































        //需修改！  隐私的另存为
        public static void SavedAs()//另存为
        {
            if (ThisMyInfo.DownloadState == "1")
            {
                MessageBox.Show("你被禁止进行下载");
            }
            else
            {
                //右键菜单的下载功能



                //可能要获取的路径名
                //string localFilePath = "", fileNameExt = "", newFileName = "", FilePath = "";
                // SaveFileDialog saveFileDialog = new SaveFileDialog();

                // localFilePath = "C: \\Users\\Overlord\\Desktop\\007ZrlpSly1gff63y2otgj30u0140e8f.jpg";
                //设置文件类型
                //书写规则例如：txt files(*.txt)|*.txt
                Loads.client.saveFileDialog1.Filter = "All files(*.*)|*.*|txt files(*.txt)|*.txt|xls files(*.xls)|*.xls";

                //设置默认文件名（可以不设置）
                //Loads.client.saveFileDialog1.FileName = localFilePath.Substring(localFilePath.LastIndexOf("\\") + 1); ;

                //主设置默认文件extension（可以不设置）
                //saveFileDialog.DefaultExt = "xml";

                //获取或设置一个值，该值指示如果用户省略扩展名，文件对话框是否自动在文件名中添加扩展名。（可以不设置）
                Loads.client.saveFileDialog1.AddExtension = true;

                //设置默认文件类型显示顺序（可以不设置）
                Loads.client.saveFileDialog1.FilterIndex = 1;

                //保存对话框是否记忆上次打开的目录
                Loads.client.saveFileDialog1.RestoreDirectory = true;

                // Show save file dialog box
                DialogResult result = Loads.client.saveFileDialog1.ShowDialog();
                int P_Length = Client.choice_term.LastIndexOf('.');//检索后缀名开始的下标
                int Max_Length = Client.choice_term.Length;//获取字符最大值
                int last_Length = Max_Length - P_Length;//获取后缀名的长度
                Client.extension_1 = Client.choice_term.Substring(P_Length, last_Length);//截取后缀名         



                //点了保存按钮进入
                if (result == DialogResult.OK)
                {
                    bool IfWait = true;
                    for (int i = 0; i < DownloadList.Length; i++)
                    {
                        if (DownloadList[i] == null)//如果下载队列为空
                        {
                            IfWait = false;

                            string sqlstr2 = string.Format("update FlieTeamLog set OperationState='正在下载' where FileDownName='{0}'", Client.fileNames);
                            DBHelps.Command(sqlstr2);

                            //DownloadList[i] = AsStatr;
                            //DownloadList[i].BeginInvoke(i, null, null);
                            break;
                        }
                        else
                        {
                            IfWait = false;//如果队列中全都在进行下载则进入等待队列
                        }
                    }
                    if (IfWait = false)
                    {
                        //进入等待队列，直至下载队列中腾出空位
                        MessageBox.Show("进入等待队列！");
                    }

                }
            }
        }











        
    }
}
